#include <stdio.h>
#include <stdlib.h>

typedef struct Vector Vector;
struct Vector {
	double x;
	double y;
	double z;
};

//dynamic programming for pow would speed this up even more, but eh
int bezier(Vector *p, Vector *newP, int p_size, double u) {
	int n = p_size - 1;
	int k = 0;
	int nfac = 1;
	int kfac = 1;
	int nkfac = 1;
	double pMul = 0; //multiplier of each point, calc'd iteratively
	double u_pow_k = 1;
	double one_minus_u_pow_nk = 1;

	//calc n! and (1-u)^n
	for (k = 1; k <= n; k++) {
		nfac *= k;
		one_minus_u_pow_nk *= (1-u);
	}

	//case k==0
	nkfac = nfac;
	pMul = one_minus_u_pow_nk;
	newP->x = p->x * pMul;
	newP->y = p->y * pMul;
	newP->z = p->z * pMul;
	p++;

	for (k = 1; k <= n; k++, p++) {
		//binomial
		kfac *= k;
		nkfac /= ((k == n)? 1 : (n - k));
		pMul = nfac / (kfac * nkfac);

		//u^k and (1-u)^(n-k)
		u_pow_k *= u;
		one_minus_u_pow_nk /= ((u == 0.0)? 1 : u);
		pMul *= u_pow_k * one_minus_u_pow_nk;

		//update newP
		newP->x += p->x * pMul;
		newP->y += p->y * pMul;
		newP->z += p->z * pMul;
	}

	return 0;

}

int main() {
	Vector *p = (Vector*)malloc(sizeof(struct Vector) * 2);
	p[0].x = p[0].y = p[0].z = 0;
	p[1].x = p[1].y = p[1].z = 1;
	p[1].x = p[1].y = p[1].z = 0.9;

	Vector newP;

	bezier(p, &newP, 2, 0.1);
	printf("%f %f %f", newP.x, newP.y, newP.z);
	return 0;
}
